package luj.tool.jnproxyan.proxy.util.data.wrap;

import luj.data.api.Data;
import luj.data.api.DataContext;
import luj.data.api.use.UseGroup;
import luj.tool.jnproxyan.proxy.database.DatabaseState;
import luj.tool.jnproxyan.proxy.util.data.load.DataGlobalLoader;
import luj.tool.jnproxyan.proxy.util.data.load.internal.DataInLoadMaker;
import luj.tool.jnproxyan.proxy.util.data.session.DataUsingStarter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class ResultGlobalLWrapper {

  public ResultGlobalLWrapper load(DataUsingStarter.Session s) {
    return load(s.db(), s.using(), s.loaded());
  }

  public ResultGlobalLWrapper load(DatabaseState dbState) {
    UseGroup using = _lujdata.createUseGroup();
    return load(dbState, using);
  }

  public ResultGlobalLWrapper load(DatabaseState dbState, UseGroup using) {
    return load(dbState, using, new HashMap<>());
  }

  public ResultGlobalLWrapper load(DatabaseState dbState, UseGroup using, Map<String, Data> loadCache) {
    ResultGlobalLWrapper result = new ResultGlobalLWrapper();
    result._dbState = dbState;
    result._useGroup = using;
    result._loadCache = loadCache;

    result._globalLoader = _globalLoader;
    result._dataWrapper = _dataWrapper;
    result._dataMaker = _dataMaker;

    return result;
  }

  // loadAndWrap
  public <T> T andWrap(Class<T> clazz) {
    Data data = _globalLoader.inject(clazz, _dbState, _loadCache).loadOrCreate();

    return _dataWrapper.inject(data, _loadCache, _useGroup).wrap(clazz);
  }

  DatabaseState _dbState;

  UseGroup _useGroup;
  Map<String, Data> _loadCache;

  @Autowired
  DataContext _lujdata;

  @Autowired
  DataGlobalLoader _globalLoader;

  @Autowired
  DataResultWrapper _dataWrapper;

  @Autowired
  DataInLoadMaker _dataMaker;
}
